package com.zyylc.wine.util;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * IO工具類，提供與IO相關操作的方�?
 * @author Edison
 *
 */
public class IOUtil {
	
	 private IOUtil() {
	 }
	 /**
     * 读取�?个流。返回包含全部内容的byte[]�?
     * 因为本方法会读取全部内容到内存中，故此方法只能在已知文件不是很大的情况下使用�?
     */
    public static byte[] read(InputStream is) {
        List<byte[]> bufferList = new ArrayList<byte[]>();
        List<Integer> lengthList = new ArrayList<Integer>();
        int total = 0;
        try {
            do {
                byte[] buffer = new byte[10000];
                int length;
                length = is.read(buffer);
                if (length == -1) {
                    break;
                }
                total += length;
                bufferList.add(buffer);
                lengthList.add(length);
            } while (true);
            byte[] result = new byte[total];
            int offset = 0;
            for (int i = 0; i < bufferList.size(); i++) {
                byte[] buf = (byte[]) bufferList.get(i);
                int len = (Integer) lengthList.get(i);
                System.arraycopy(buf, 0, result, offset, len);
                offset += len;
            }
            return result;
        } catch (Exception exp) {
            throw new RuntimeException("readInputStream error!", exp);
        }
    }
    
    public static void close(Closeable resource) {
		try {
			if (resource != null) {
				resource.close();
			}
		} catch (IOException exp) {
			exp.printStackTrace();
		}
	}
    
    /**
     * 写文本文件�??
     * @param fileName 文件名称�?
     * @param content  内容�?
     */
    public static void writeAsText(String fileName, String content) {
        writeAsText(new File(fileName), content);
    }

    /**
     * 写文本文件�??
     * @param file 文件�?
     * @param content  内容�?
     */
    public static void writeAsText(File file, String content) {
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(new FileOutputStream(file));
            osw.write(content, 0, content.length());
        } catch (Exception exp) {
            throw new RuntimeException("writeTextFile error, file: " + file, exp);
        } finally {
            close(osw);
        }
    }

    /**
     * 写文�?.默认Buffer大小�?100k�?
     * @param file 文件
     * @param is   内容
     */
    public static void write(File file, InputStream is) {
        write(file, is, 1024 * 100);
    }

    /**
     * 写文件�??
     * @param file 文件
     * @param is   内容
     * @param bufferSize Buffer 大小
     */
    public static void write(File file, InputStream is, int bufferSize) {
        BufferedOutputStream os = null;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file));
            byte[] buffer = new byte[bufferSize];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }

        } catch (Exception exp) {
            throw new RuntimeException("writeFile error, file: " + file, exp);
        } finally {
            close(os);
        }
    }

    /**
     * 
     * @param file 将一个byte数组写入到file
     * @param bytes byte数组
     */
    public static void write(File file, byte[] bytes) {
        int bufferSize = 10 * 1024;
        BufferedOutputStream os = null;
        InputStream is = null;
        try {
            os = new BufferedOutputStream(new FileOutputStream(file));
            is = new ByteArrayInputStream(bytes);
            byte[] buffer = new byte[bufferSize];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
            os.flush();
        } catch (Exception exp) {
            throw new RuntimeException("writeFile error, file: " + file, exp);
        } finally {
            close(os);
            close(is);
        }
    }

    /**
     * 输入输出。将is流中的内容输出到os中去�?
     * @param os 输出流�??
     * @param is 输入流�??
     * @param bufferSize Buffer大小�?
     */
    public static void write(OutputStream os, InputStream is, int bufferSize) {
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(os);
            byte[] buffer = new byte[bufferSize];
            int len = -1;
            while ((len = is.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.flush();
        } catch (Exception exp) {
            throw new RuntimeException("write error", exp);
        } finally {
            //close(bos);  // close os is up to the invoker.
        }
    }
}
